/**
 * 
 */
package edu.tsinghua.mrpvc.device.light;

import java.util.Calendar;
import java.util.Hashtable;
import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventHandler;
import org.osgi.util.tracker.ServiceTracker;

import edu.tsinghua.mrpvc.device.LightDevice;


/**
 * @author Tangjian Deng & Wei Feng
 *
 */
public class LightDeviceImpl implements LightDevice, EventHandler{
	String ID;
	int level;
	int powerState;
	boolean valid;
	ServiceTracker tracker;
	
	public LightDeviceImpl(BundleContext context, String ID){
		this.ID = ID;
		this.level = 0;
		this.powerState = 0;
		this.valid = true;
		tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
		tracker.open();
	}
	
	private void generEvent(){
		System.out.println(Calendar.getInstance().getTime().toLocaleString() + 
				" Light: state changed and post event");
		EventAdmin eventAdmin = (EventAdmin) tracker.getService();
		if(eventAdmin != null){
			Map<String, String> propers = new Hashtable<String, String>();
			propers.put(LightDevice.EVENT_PROPER_POWER, powerState == 1 ? LightDevice.Constants.POWER_ON : LightDevice.Constants.POWER_OFF);
			if(Integer.toString(level).equals(LightDevice.Constants.LIGHT_LEVEL_ZERO)){
				propers.put(LightDevice.EVENT_PROPER_LIGHT_LEVEL, LightDevice.Constants.LIGHT_LEVEL_ZERO);
			}
			else if(Integer.toString(level).equals(LightDevice.Constants.LIGHT_LEVEL_ONE)){
				propers.put(LightDevice.EVENT_PROPER_LIGHT_LEVEL, LightDevice.Constants.LIGHT_LEVEL_ONE);
			}
			else if(Integer.toString(level).equals(LightDevice.Constants.LIGHT_LEVEL_TWO)){
				propers.put(LightDevice.EVENT_PROPER_LIGHT_LEVEL, LightDevice.Constants.LIGHT_LEVEL_TWO);
			}
			else if(Integer.toString(level).equals(LightDevice.Constants.LIGHT_LEVEL_THREE)){
				propers.put(LightDevice.EVENT_PROPER_LIGHT_LEVEL, LightDevice.Constants.LIGHT_LEVEL_THREE);
			}
			else if(Integer.toString(level).equals(LightDevice.Constants.LIGHT_LEVEL_FOUR)){
				propers.put(LightDevice.EVENT_PROPER_LIGHT_LEVEL, LightDevice.Constants.LIGHT_LEVEL_FOUR);
			}			
			propers.put(LightDevice.EVENT_PROPER_ID, ID);
			propers.put(LightDevice.EVENT_PROPER_ISVALID, valid == true ? LightDevice.Constants.ISVALID_TRUE : LightDevice.ISVALID_FALSE);
			Event event = new Event(LightDevice.EVENT_TOPIC_STATE, propers);
			eventAdmin.postEvent(event);
		}
	}
	
	@Override
	public int downLevel() {
		// TODO Auto-generated method stub
		level--;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Light: down Level executed");
		generEvent();
		return level;
	}

	@Override
	public String getID() {
		// TODO Auto-generated method stub
		return ID;
	}

	@Override
	public int getState() {
		// TODO Auto-generated method stub
		return powerState;
	}

	@Override
	public boolean isValid() {
		// TODO Auto-generated method stub
		return valid;
	}

	@Override
	public int powerOff() {
		// TODO Auto-generated method stub
		powerState = Integer.valueOf(Constants.POWER_OFF);
		level = Integer.valueOf(Constants.LIGHT_LEVEL_ZERO);
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Light: PowerOff executed");
		generEvent();
		return 1;
	}

	@Override
	public int powerOn() {
		// TODO Auto-generated method stub
		powerState = Integer.valueOf(Constants.POWER_ON);
		level = Integer.valueOf(Constants.LIGHT_LEVEL_FOUR);
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Light: PowerOn executed");
		generEvent();
		return 1;
	}
	
	public int setLevel(int level) {
		// TODO Auto-generated method stub
		this.level = level;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Light: set Level executed");
		generEvent();
		return level;
	}

	@Override
	public int upLevel() {
		// TODO Auto-generated method stub
		this.level ++;
		System.out.print(Calendar.getInstance().getTime().toLocaleString() + " ");
		System.out.println("Light: up Level executed");
		generEvent();
		return level;
	}

	
	 @Override
	public void handleEvent(Event event) {
		// TODO Auto-generated method stub
		 if(event.getTopic().equals(LightDevice.EVENT_TOPIC_ISVALID)){
			 if(event.getProperty(LightDevice.EVENT_PROPER_ID) != null && event.getProperty(LightDevice.EVENT_PROPER_ID).equals(ID)){
				 generEvent();
			 }
			 else{
				 System.out.println("***LightDevice ID not match***");
			 }
		 }
		 else if(event.getTopic().equals(LightDevice.EVENT_TOPIC_POWER)){
			 if(event.getProperty(LightDevice.EVENT_PROPER_ID) != null && event.getProperty(LightDevice.EVENT_PROPER_ID).equals(ID)){
				 if(event.getProperty(LightDevice.EVENT_PROPER_POWER) != null && event.getProperty(LightDevice.EVENT_PROPER_POWER).equals(LightDevice.Constants.POWER_OFF)){
					 this.powerState = 0;
				 }
				 else if(event.getProperty(LightDevice.EVENT_PROPER_POWER) != null && event.getProperty(LightDevice.EVENT_PROPER_POWER).equals(LightDevice.Constants.POWER_ON)){
					 this.powerState = 1;
				 }
				 generEvent();
			 }
			 else{
				 System.out.println("***LightDevice ID not match***");
			 }
		 }
		 else if(event.getTopic().equals(LightDevice.EVENT_TOPIC_LEVEL)){
			 if(event.getProperty(LightDevice.EVENT_PROPER_ID) != null && event.getProperty(LightDevice.EVENT_PROPER_ID).equals(ID)){
				 if(event.getProperty(LightDevice.EVENT_PROPER_LIGHT_LEVEL) != null){
					 this.level = Integer.parseInt(event.getProperty(LightDevice.EVENT_PROPER_LIGHT_LEVEL).toString());
				 }
				 generEvent();
			 }
			 else{
				 System.out.println("***LightDevice ID not match***");
			 }
		 }
	}
	
	

}
